<!--
 * @Author: fengshan0525 2735332396@qq.com
 * @Date: 2023-03-18 15:30:03
 * @LastEditors: asanupup 15465106+asanupup@user.noreply.gitee.com
 * @LastEditTime: 2025-07-22 17:12:40
 * @FilePath: \b-vue3-ts-ele-template\src\views\system\RolesManage.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div class="app-container">
    <el-form :inline="true" :model="queryForm" ref="queryFormRef">
      <el-form-item label="角色名" prop="roleName">
        <el-input v-model="queryForm.roleName" placeholder="角色名" clearable />
      </el-form-item>
      <el-form-item label="权限字符" prop="roleKey">
        <el-input v-model="queryForm.roleKey" placeholder="权限字符" clearable />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="queryForm.status" placeholder="选择状态" style="width: 120px;" @change="queryRolesList">
          <el-option label="停用" value="0"></el-option>
          <el-option label="启用" value="1"></el-option>
        </el-select>
      </el-form-item>
    </el-form>
    <ActionButtons @reset="handleReset" @query="queryRolesList"></ActionButtons>
    <el-button type="primary" size="small" @click="handleCreateRole">新增角色</el-button>
    <BaseTable :table-columns="tableColumns" :table-data="tableData" :options="options" :page-size="page.pageSize"
      :page-num="page.pageNum" :total="page.total">
      <template v-slot:operation="{ row }">
        <el-button text type="primary" @click="handleEdit(row)">编辑</el-button>
        <el-button text style="color: red;" @click="handleDel(row)">删除</el-button>
      </template>
    </BaseTable>
    <Dialog @close="handleDialogClose" @confirm="handleDialogConfirm" ref="dialogRef" :title="dialogOptions.title"
      :width="dialogOptions.width">
      <template v-slot:content>
        <el-form :model="dialogForm" :rules="dialogFormRules" label-position="left" ref="diaFormRef">
          <el-form-item label="角色名称" prop="roleName" label-width="100px">
            <el-input v-model="dialogForm.roleName" placeholder="角色名称"></el-input>
          </el-form-item>
          <el-form-item label="权限字符" prop="roleKey" label-width="100px">
            <el-input v-model="dialogForm.roleKey" placeholder="权限字符"></el-input>
          </el-form-item>
          <el-form-item label="角色ID" prop="roleId" label-width="100px">
            <el-input-number :min="0" :max="100" v-model="dialogForm.roleId" placeholder="角色ID"></el-input-number>
          </el-form-item>
          <el-form-item label="状态" prop="status" label-width="100px">
            <el-radio-group v-model="dialogForm.status">
              <el-radio label="1">启用</el-radio>
              <el-radio label="0">停用</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="顺序" prop="order" label-width="100px">
            <el-input-number :min="0" v-model="dialogForm.order" placeholder="顺序"></el-input-number>
          </el-form-item>
          <el-form-item label="菜单权限" prop="menuIdList">
            <el-tree :data="treeData" ref="treeRef" node-key="menuId" :props="defaultProps" show-checkbox></el-tree>
          </el-form-item>
        </el-form>
      </template>
    </Dialog>
  </div>
</template>
<script lang='ts' setup>
import { ref, reactive } from 'vue'
import FSMessage from '@/utils/message'
import type { FormInstance } from 'element-plus'
import useHooksTable from '@/views/System/RolesManage/useHooksTable'
import useHooksDialog from '@/views/System/RolesManage/useHooksDialog'
import { createRoleAPI, delRoleAPI, updateRoleAPI, getRoleDetail } from '@/api/roles'
import { resetForm, processMenuChildren, validateForm } from '@/utils/tools'
import { getMenuListChildrenAPI } from '@/api/menu'
import { ElTree } from 'element-plus'

/* ------------------------------ variable ------------------------------ */
const queryFormRef = ref<FormInstance>()
const dialogRef = ref()
const diaFormRef = ref<FormInstance>()
const treeRef = ref<InstanceType<typeof ElTree>>()
const { tableColumns, tableData, page, options, queryForm, queryRolesList, handleReset } = useHooksTable(queryFormRef)
const { dialogForm, dialogFormRules, dialogOptions, defaultProps, treeData } = useHooksDialog(dialogRef)
/* ------------------------------ function ------------------------------ */

/**
 * @breif: 编辑角色
 * @param {*} row
 * @return {*}
 */
const handleEdit = async (row) => {
  try {
    dialogOptions.openType = 2
    dialogOptions.title = '编辑角色'
    dialogRef.value.visiableDialog()
    const res = await getRoleDetail(row.roleId)
    if (!treeData.value) {
      const result = await getMenuListChildrenAPI({})
      treeData.value = processMenuChildren(result.data)
    }
    treeRef.value.setCheckedKeys(res.data.menus)
    // @ts-ignore
    dialogForm.value = res.data
  } catch (e) {
    console.log(e)
  }
}

/**
 * @breif: 新增角色
 * @return {*}
 */
const handleCreateRole = async () => {
  try {
    dialogOptions.openType = 1
    dialogOptions.title = '新增角色'
    dialogRef.value.visiableDialog()
    const res = await getMenuListChildrenAPI({})
    treeData.value = processMenuChildren(res.data)
    treeRef.value.setCheckedKeys([])
  } catch (e) {
    console.log(e)
  }
}

/**
 * @breif: 删除角色
 * @param {*} row
 * @return {*}
 */
const handleDel = (row) => {
  FSMessage.confirm('删除后不可恢复，是否确认删除?', '提示').then(() => {
    delRoleAPI(row.roleId).then(() => {
      FSMessage.success('删除成功')
      queryRolesList()
    })
  }).catch(() => {
    FSMessage.info('已取消删除')
  })
}

/**
 * @breif: 弹窗确认按钮事件
 * @param {*} formEl
 * @return {*}
 */
const handleDialogConfirm = async () => {
  try {
    await validateForm(diaFormRef.value)
    dialogForm.value.menus = treeRef.value.getCheckedKeys()
    dialogOptions.openType === 1 ? await createRoleAPI(dialogForm.value) : await updateRoleAPI(dialogForm.value)
    FSMessage.success('操作成功')
    dialogRef.value.invisiableDialog()
    resetForm(diaFormRef.value)
    queryRolesList()
  } catch (e) {
    console.log(e)
  }
}

const handleDialogClose = () => {
  resetForm(diaFormRef.value)
}
queryRolesList()
</script>
<style scoped lang='less'></style>
